/**
 * @file job_task_architecture_example.cpp
 * @brief Example demonstrating the corrected Job-Task architecture
 * 
 * This example shows how:
 * 1. Job is a container/coordinator, not an execution unit
 * 2. Task is the actual execution unit that gets scheduled
 * 3. Each Task knows which Job it belongs to
 * 4. Each Task can only belong to one Job
 */

#include "include/job.hpp"
#include "include/task.hpp"
#include "include/kernel.hpp"
#include "include/logger.hpp"

using namespace qOS;

// Example task callbacks
void task1Callback(event_t e, uint64_t securityToken)
{
    logger::out(logger::info) << "Task 1 executing";
    // Task 1 implementation here
}

void task2Callback(event_t e, uint64_t securityToken)
{
    logger::out(logger::info) << "Task 2 executing";
    // Task 2 implementation here
}

void task3Callback(event_t e, uint64_t securityToken)
{
    logger::out(logger::info) << "Task 3 executing";
    // Task 3 implementation here
}

int main()
{
    // Get OS core instance (singleton pattern)
    core& os = core::getInstance();
    
    // Initialize OS with system tick function
    os.init();
    
    // Create tasks (the actual execution units)
    task tasks[3];
    
    // Configure tasks
    tasks[0].setCallback(task1Callback);
    tasks[0].setName("Task1");
    
    tasks[1].setCallback(task2Callback);
    tasks[1].setName("Task2");
    
    tasks[2].setCallback(task3Callback);
    tasks[2].setName("Task3");
    
    // Create job configuration - try SEQUENTIAL first
    JobConfig jobConfig("SequentialJob", JobExecutionMode::SEQUENTIAL);
    jobConfig.timeout = 5000;  // 5 seconds timeout
    jobConfig.maxRetries = 3;
    
    // Create job (container/coordinator)
    Job exampleJob(jobConfig);
    
    // Submit job to scheduler (includes initialization)
    if (!exampleJob.submit(os, tasks, 3)) {
        logger::out(logger::error) << "Failed to submit job";
        return -1;
    }
    
    // Start the scheduler (this starts the task scheduling loop)
    os.run();
    for (;;) {
        // Main loop - tasks are scheduled by os.run()
    }
    
    return 0;

    /* 
     * UNCOMMENT BELOW TO TEST PARALLEL EXECUTION:
     * 
     * // Create a parallel job for comparison
     * JobConfig parallelJobConfig("ParallelJob", JobExecutionMode::PARALLEL);
     * parallelJobConfig.timeout = 5000;
     * parallelJobConfig.maxRetries = 3;
     * 
     * Job parallelJob(parallelJobConfig);
     * 
     * // Create separate tasks for parallel execution
     * task parallelTasks[3];
     * parallelTasks[0].setCallback(task1Callback);
     * parallelTasks[0].setName("ParallelTask1");
     * parallelTasks[1].setCallback(task2Callback);
     * parallelTasks[1].setName("ParallelTask2");
     * parallelTasks[2].setCallback(task3Callback);
     * parallelTasks[2].setName("ParallelTask3");
     * 
     * if (!parallelJob.initialize(parallelTasks, 3)) {
     *     logger::out(logger::error) << "Failed to initialize parallel job";
     *     return -1;
     * }
     * 
     * if (!parallelJob.submit(os)) {
     *     logger::out(logger::error) << "Failed to submit parallel job";
     *     return -1;
     * }
     * 
     * // Add parallel tasks to scheduler
     * for (size_t i = 0; i < 3; i++) {
     *     if (!os.add(parallelTasks[i], parallelTasks[i].getCallback(), core::MEDIUM_PRIORITY, nullptr)) {
     *         logger::out(logger::error) << "Failed to add parallel task " << i << " to scheduler";
     *     }
     * }
     * 
     * // In SEQUENTIAL mode: Tasks execute one after another
     * // In PARALLEL mode: All tasks can execute simultaneously
     */
}

/*
 * ARCHITECTURAL CORRECTIONS MADE:
 * 
 * 1. Job is no longer an execution unit - it's a container/coordinator
 * 2. Task is the actual execution unit that gets scheduled by the OS
 * 3. Each Task has a pointer to its parent Job (parentJob member)
 * 4. Tasks can only belong to one Job (enforced by setParentJob)
 * 5. Tasks automatically notify their parent Job about execution status
 * 6. Jobs can pause/resume, and Tasks check parent Job status before executing
 * 7. Job coordinates Tasks but doesn't execute them directly
 * 
 * USAGE PATTERN:
 * 1. Create Tasks with their callbacks
 * 2. Create Job with configuration
 * 3. Submit Job to scheduler (includes initialization and task submission)
 * 4. Tasks automatically coordinate with their parent Job
 */
